package com.wangbo.hc;

import cn.hutool.core.io.FileUtil;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;

import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicInteger;

public class TestHCNetSDK {

    public static final String WINDOWS_LIB_HOME = "D:\\lib\\windows_hc";
    public static final String LINUX_LIB_HOME = "F:\\lib\\linux";
    public static final HCNetSDK hcNetSDK = HCNetSDK.INSTANCE;

    public static final String IP = "192.168.88.204";
    public static final int PORT = 8000;
    public static final String USERNAME = "admin";
    public static final String PASSWORD = "szlx12345";

    public static MyFMSGCallBack myFMSGCallBack = null; // 摄像头消息回调
    public static final LinkedList<SnapDTO> queue = new LinkedList<>();

    public static final AtomicInteger PIC_ID = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        init();
        // 登录
        int lUserID = login();
        System.out.printf("登录userId：%d%n", lUserID);

        // 布防
//        int lAlertHandle = alarm(lUserID);
//        for (int i = 0; i < 100; i++) {
//            Thread.sleep(1000L);
//            while (!queue.isEmpty()) {
//                SnapDTO snapDTO = queue.poll();
//                FileUtil.writeBytes(snapDTO.getSmallImageBytes(), "D:\\temp\\small_" + PIC_ID.incrementAndGet() + ".jpg");
//                FileUtil.writeBytes(snapDTO.getBigImageBytes(), "D:\\temp\\big_" + PIC_ID.incrementAndGet() + ".jpg");
//                System.out.printf("收到抓拍：%d%n", snapDTO.getPicId());
//            }
//        }

        // 工作状态
//        boolean state = getWorkingState(lUserID);
//        System.out.printf("摄像头工作状态：%b%n", state);

        // 手动抓拍
        manualSnap(lUserID);
    }

    public static void init() {
        HCNetSDK.BYTE_ARRAY byteArray1 = new HCNetSDK.BYTE_ARRAY(256);
        HCNetSDK.BYTE_ARRAY byteArray2 = new HCNetSDK.BYTE_ARRAY(256);

        String libcryptoPath = WINDOWS_LIB_HOME + "\\libeay32.dll";
        String libsslPath = WINDOWS_LIB_HOME + "\\ssleay32.dll";

        System.arraycopy(libcryptoPath.getBytes(), 0, byteArray1.byValue, 0, libcryptoPath.length());
        byteArray1.write();
        hcNetSDK.NET_DVR_SetSDKInitCfg(3, byteArray1.getPointer());

        System.arraycopy(libsslPath.getBytes(), 0, byteArray2.byValue, 0, libsslPath.length());
        byteArray2.write();
        hcNetSDK.NET_DVR_SetSDKInitCfg(4, byteArray2.getPointer());

        HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
        System.arraycopy(WINDOWS_LIB_HOME.getBytes(), 0, struComPath.sPath, 0, WINDOWS_LIB_HOME.length());
        struComPath.write();
        hcNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());

        if (!hcNetSDK.NET_DVR_Init()) {
            System.out.println("初始化失败");
        }

        // 通用参数配置
        HCNetSDK.NET_DVR_LOCAL_GENERAL_CFG generalCfg = new HCNetSDK.NET_DVR_LOCAL_GENERAL_CFG();
        generalCfg.byAlarmJsonPictureSeparate = 1; //控制JSON透传报警数据和图片是否分离，0-不分离，1-分离（分离后走COMM_ISAPI_ALARM回调返回）
        generalCfg.write();
        if(!hcNetSDK.NET_DVR_SetSDKLocalCfg(17, generalCfg.getPointer())) {
            System.out.println("NET_DVR_SetSDKLocalCfg失败");
        }

        hcNetSDK.NET_DVR_SetLogToFile(3, "D:\\temp\\", true);
    }

    /**
     * 登录
     */
    public static int login() {
        HCNetSDK.NET_DVR_DEVICEINFO_V30 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
        return hcNetSDK.NET_DVR_Login_V30(IP, (short) PORT, USERNAME, PASSWORD, deviceInfo);
    }

    /**
     * 布防(失败)
     */
    public static int alarm(int lUserID) {
        if (myFMSGCallBack == null) {
            myFMSGCallBack = new MyFMSGCallBack(queue);
        }

        Pointer pUser = null;
        hcNetSDK.NET_DVR_SetDVRMessageCallBack_V31(myFMSGCallBack, pUser);

        // 报警布防设置
        HCNetSDK.NET_DVR_SETUPALARM_PARAM setupAlarmParam = new HCNetSDK.NET_DVR_SETUPALARM_PARAM();
        setupAlarmParam.dwSize = setupAlarmParam.size();
        setupAlarmParam.byLevel = 0;  //布防优先级，0-一等级（高），1-二等级（中），2-三等级（低）
        setupAlarmParam.byAlarmInfoType = 1; //上传报警信息类型（抓拍机支持），0-老报警信息（NET_DVR_PLATE_RESULT），1-新报警信息(NET_ITS_PLATE_RESULT)2012-9-28
        setupAlarmParam.byDeployType = 2; //布防类型：0-客户端布防，1-实时布防
        setupAlarmParam.byCustomCtrl = 1; // 表示支持副驾驶人脸子图上传: 0-不上传,1-上传
        setupAlarmParam.write(); // 将结构体的字段值写入到ThreadLocal中

        int lAlarmHandle = hcNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, setupAlarmParam);
        if (lAlarmHandle == -1) {
            System.out.printf("布防失败，错误码为:%d%n", hcNetSDK.NET_DVR_GetLastError());
        } else {
            System.out.println("布防成功");
        }

        return lAlarmHandle;
    }

    /**
     * 获取摄像头工作状态
     */
    public static boolean getWorkingState(int userId) {
        HCNetSDK.NET_DVR_WORKSTATE_V30 workstate = new HCNetSDK.NET_DVR_WORKSTATE_V30();
        return hcNetSDK.NET_DVR_GetDVRWorkState_V30(userId, workstate);
    }

    /**
     * 手动抓拍
     */
    public static void manualSnap(int userId) {
        HCNetSDK.NET_DVR_MANUALSNAP param = new HCNetSDK.NET_DVR_MANUALSNAP();
        param.read();
        param.byOSDEnable = 0;
        param.byChannel = 1;
        param.byLaneNo = 1;
        param.write();

        HCNetSDK.NET_DVR_PLATE_RESULT result = new HCNetSDK.NET_DVR_PLATE_RESULT();
        result.read();
        result.pBuffer1 = new Memory(2 * 1024 * 1024);
        result.pBuffer2 = new Memory(2 * 1024 * 1024);
        result.write();

        boolean success = hcNetSDK.NET_DVR_ManualSnap(userId, param, result);
        if (success) {
            System.out.printf("近景图size: %d kb%n", result.dwPicLen / 1024);
            System.out.printf("远景图size: %d kb%n", result.dwFarCarPicLen / 1024);
            byte[] imgBytes1 = result.pBuffer1.getByteArray(0, result.dwPicLen);
            byte[] imgBytes2 = result.pBuffer5.getByteArray(0, result.dwFarCarPicLen);
            FileUtil.writeBytes(imgBytes1, "D:\\tmp\\a.jpg");
            FileUtil.writeBytes(imgBytes2, "D:\\tmp\\b.jpg");
        }
    }
}
